package com.javaspeak.designpatterns.go4.structural.flyweight;

/**
 * When there are many instances of a class which use the same data across many
 * instances then that data should be factored out into a read only instance of
 * a class that allows the data to be shared between many instances.
 * <p>
 * In this example we are drawing shapes on a canvas at different locations.
 * Some of the data for a given shape is the same.  For example a square looks
 * the same. Other data could be different; for example the location of a
 * square on the canvas.
 * <p>
 * We have factored out the information about rendering a square or triangle
 * into a flyweight object which can be referenced by many CanvasElements
 * wishing to draw a square or triangle.  The CanvasElements reference the
 * shape they are interested in and provide unique data such as the location
 * to draw the shape at.
 * <p>
 * When there are many references to the same flyweight objects this can
 * substantially reduce memory requirements.
 *
 * @author John Dickerson
 */
public class ApplicationFlyweight {

    /**
     * Adds CanvasElements to the canvas and then renders them by printing
     * to System.out. The adding of the CanvasElements to the canvas involves
     * writing individual pixels from the canvas Shapes to a multi dimensional
     * array.
     */
    public void drawCanvas(){

        Canvas canvas = new CanvasImpl();

        canvas.addCanvasElement(
               new CanvasElement( ShapeCache.getSquare(), 0, 0 ) );

        canvas.addCanvasElement(
                new CanvasElement( ShapeCache.getSquare(), 0, 6 ) );

        canvas.addCanvasElement(
                new CanvasElement( ShapeCache.getTriangle(), 6, 0 ) );

        canvas.addCanvasElement(
                new CanvasElement( ShapeCache.getTriangle(), 6, 6 ) );

        canvas.render();
    }


    /**
     * Main method
     *
     * @param args
     */
    public static void main(String[] args) {

        ApplicationFlyweight application = new ApplicationFlyweight();
        application.drawCanvas();
    }
}
